//
//  ViewController.m
//  CamH
//
//  Created by ghu on 12-8-8.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "CameraViewController.h"
#import "ImageHelper.h"
#import "wxFDIF.h"

#define FOCUS_FRAME_WIDTH   57
#define FOCUS_FRAME_HEIGHT  57
#define MAX_ZOOM_SCALE      3.0
#define MIN_ZOOM_SCALE      1.0

#define MAX_FACE_COUNT      10

@interface CameraViewController()
{
    UIActivityIndicatorView *_spinner;
    CGPoint _focusPoint;
    CGFloat _previewScale;
    
    NSInteger   _faceCount;
    CGRect      _faceRect[MAX_FACE_COUNT];
    UIImageView *_pImageFaces[MAX_FACE_COUNT];
}

@end

@implementation CameraViewController
@synthesize m_pBtnTakePhoto;
@synthesize m_pBtnFaceDetect;
@synthesize m_pViewPreview;
@synthesize m_captureMode;
@synthesize m_pImageViewFocus;
@synthesize m_pFaceDetectManager;
@synthesize m_pVideoPreviewLayer;
@synthesize m_pZoomSlider;
@synthesize m_pBtnFlash;
@synthesize m_pBtnSwitchCamera;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        [CamCaptureManager singleton].delegate = self;
        m_captureMode = CAMERA_CAPTUREMODE_PREVIEW;
        
        self.m_pFaceDetectManager = [[FaceDetectManager alloc] initWithWidth:240 height:320];
        
        self->_faceCount = 0;
        for (int i = 0; i<MAX_FACE_COUNT; i++)
        {
            _pImageFaces[i] = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
            _pImageFaces[i].hidden = YES;
            [_pImageFaces[i] setImage: [ImageHelper GetResIconNamed:@"CameraPage_FaceRect.png"]];
            [self.view addSubview:_pImageFaces[i]];
        }
        
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    self.title = @"主界面";
    
    if ([CamCaptureManager singleton].m_pSession == nil)
    {
        if ( [[CamCaptureManager singleton] setupSession] )
        {
            // Create video preview layer and add it to the UI
			AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:                                                                       [CamCaptureManager singleton].m_pSession];
			CALayer *viewLayer = [self.m_pViewPreview layer];
            // viewLayer adds
            viewLayer.masksToBounds = YES;
			
			CGRect bounds = [self.m_pViewPreview bounds];
			[newCaptureVideoPreviewLayer setFrame:bounds];
			
			if ([newCaptureVideoPreviewLayer isOrientationSupported])
				[newCaptureVideoPreviewLayer setOrientation:AVCaptureVideoOrientationPortrait];
			[newCaptureVideoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
            
			[viewLayer insertSublayer:newCaptureVideoPreviewLayer below:[[viewLayer sublayers] objectAtIndex:0]];
		
			self.m_pVideoPreviewLayer = newCaptureVideoPreviewLayer;
            [newCaptureVideoPreviewLayer release];
            [self changeSessionState:YES];
            [CamCaptureManager singleton].m_bEnableVideoOutput = YES;
            
            _spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
            [_spinner setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
            _spinner.autoresizingMask = UIViewAutoresizingFlexibleTopMargin     |
                                        UIViewAutoresizingFlexibleBottomMargin  |
                                        UIViewAutoresizingFlexibleLeftMargin    |
                                        UIViewAutoresizingFlexibleRightMargin;
            [self.view addSubview:_spinner];
            
            // 单击-->自动定焦
            UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapToAutoFocus:)];
            singleTap.delegate = (id)self;
            [singleTap setNumberOfTapsRequired:1];
            [self.m_pViewPreview addGestureRecognizer:singleTap];
            
            // 手指捏-->相机变焦
            UIPinchGestureRecognizer *twoFingerPinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPintch:)];
            twoFingerPinch.delegate = (id)self;
            [self.m_pViewPreview addGestureRecognizer:twoFingerPinch];
            _previewScale = 1.0f;
            
            //变焦滑动条初始化
            m_pZoomSlider = [[ZoomViewController alloc] init];
            m_pZoomSlider.zoomDelegate = (id)self;
            m_pZoomSlider.view.frame = CGRectMake(0, 360, 320, 65);
            m_pZoomSlider.view.hidden = YES;
            [self.view addSubview:m_pZoomSlider.view];
            
            if (![[CamCaptureManager singleton] hasFlash])
                self.m_pBtnFlash.hidden = YES;
            if ([[CamCaptureManager singleton] cameraCount] <= 1)
                self.m_pBtnSwitchCamera.hidden = YES;
        }    
    }
}

//  using KVO to monitor the value of the MediaManager state
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
//    if ([keyPath isEqualToString:@"scannerState"]) {
//        ARCMediaManagerState state = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
//        CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^(void) {
//            [self onChangingMediaManagerState:state];
//        });
//        
//    }
//    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)changeSessionState:(BOOL)bStart
{
    /**
     * Show close camera animation.
     * NOTE: the start camera animation will be shown in captureManager:changeSessionState:
     */
    if (!bStart && [[CamCaptureManager singleton].m_pSession isRunning])
    {
        if ([NSThread isMainThread]) {
            [self showCameraAnimation:NO];
        }
        else {
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                [self showCameraAnimation:YES];
            });
        }
    }    
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL isRunning = [[CamCaptureManager singleton].m_pSession isRunning];
        if (bStart && !isRunning) {
            [[CamCaptureManager singleton].m_pSession startRunning];
        }
        else if (!bStart && isRunning) {
            [[CamCaptureManager singleton].m_pSession stopRunning];
        }
    });
}

- (void) captureManager:(CamCaptureManager *)captureManager changeSessionState:(BOOL)bRunning
{
    if (bRunning) {
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            [self showCameraAnimation:YES];
        });
    }
}

- (void)showCameraAnimation:(BOOL)bOnOff
{
    // TODO show animation
}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self changeSessionState:YES];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
	[super viewWillDisappear:animated];
    [self changeSessionState:NO];
}

- (void)viewDidDisappear:(BOOL)animated
{
	[super viewDidDisappear:animated];
}

// 只允许Portrait一种显示
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIDeviceOrientationPortrait);
}

// 显示等待转盘
- (void)showSpinner
{
    [_spinner sizeToFit];
    [_spinner startAnimating];
    _spinner.center = self.m_pViewPreview.center;
}

// 结束等待转盘
-(void)hideSpinner
{
    [_spinner stopAnimating];
    _spinner.hidden = YES;

}

-(void) updateViewWithFaceCount:(int)faceCount faceRects:(CGRect*)rects
{
    int i;
    for (i=0; i<faceCount; i++)
    {
        _pImageFaces[i].hidden = NO;
        _pImageFaces[i].frame = CGRectMake(rects[i].origin.x, rects[i].origin.y, rects[i].size.width, rects[i].size.height);
    }
    for (; i<MAX_FACE_COUNT; i++) {
        _pImageFaces[i].hidden = YES;
    }
}

/* **************************************************************************
 * 定焦+变焦
 * *************************************************************************/
- (void)valueChange:(CGFloat)value
{
    //calculate zoom bar scale to preview scale
    CGFloat currentScale = [[self.m_pViewPreview.layer valueForKeyPath:@"transform.scale"] floatValue];
    
    CGFloat newScale = 1.0 + value*1.40;
    newScale = MIN(newScale, MAX_ZOOM_SCALE / currentScale);
    newScale = MAX(newScale, MIN_ZOOM_SCALE / currentScale);
    
    CGAffineTransform transform = CGAffineTransformScale([self.m_pViewPreview transform], newScale, newScale);
    self.m_pViewPreview.transform = transform;
  
    [self startZoomBarDisplayTimer];
}

- (void)cancelZoomBarDisplayTimer
{
    if (_zoomHideTimer) {
        [_zoomHideTimer invalidate];
        _zoomHideTimer = nil;
    }
}

- (void)startZoomBarDisplayTimer
{
    [self cancelZoomBarDisplayTimer];
    _zoomHideTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                      target:self
                                                    selector:@selector(hideZoomBar)
                                                    userInfo:nil
                                                     repeats:NO];
}

- (void)toggleZoomBar:(BOOL)bHide
{
    _bZoomSliderHidden = bHide;
    
    if(_bZoomSliderHidden == YES)
        m_pZoomSlider.view.hidden = YES;
    else
        m_pZoomSlider.view.hidden = NO;
    
    if ( ! _bZoomSliderHidden ) {
        [self startZoomBarDisplayTimer];
    }
}

// 隐藏变焦滑动条
- (void)hideZoomBar
{
    if (_zoomHideTimer && [_zoomHideTimer isValid]) {
        [_zoomHideTimer invalidate];
        _zoomHideTimer = nil;
    }
    [self toggleZoomBar:YES];
}

// 显示变焦滑动条
- (void)showZoomBar
{
    [self toggleZoomBar:NO];
}

// 单击-->自动定焦
- (void)tapToAutoFocus:(UIGestureRecognizer *)gestureRecognizer
{    
    CGPoint tapPoint = [gestureRecognizer locationInView:self.m_pViewPreview];
    CGSize frameSize = self.m_pViewPreview.frame.size;
    
    _focusPoint = [CamUtility convertToPointOfInterestFromViewCoordinates:tapPoint inframeSize:frameSize VideoPreviewLayer:self.m_pVideoPreviewLayer];
    
    CGFloat currentScale = [[self.m_pViewPreview.layer valueForKeyPath:@"transform.scale"] floatValue];
    
    CGRect rect = [m_pImageViewFocus frame];
    rect.size.width = FOCUS_FRAME_WIDTH / currentScale;
    rect.size.height = FOCUS_FRAME_HEIGHT / currentScale;
    rect.origin.x = tapPoint.x - rect.size.width / 2;
    rect.origin.y = tapPoint.y - rect.size.height / 2;
    
    CGRect srcRect = CGRectMake(0,0,0,0);
    srcRect.size.width =  rect.size.width*3/2;
    srcRect.size.height = rect.size.height*3/2;
    srcRect.origin.x = rect.origin.x - (srcRect.size.width-rect.size.width)/2;
    srcRect.origin.y = rect.origin.y - (srcRect.size.height-rect.size.height)/2;
    
    [m_pImageViewFocus setHidden:NO];
    [m_pImageViewFocus setFrame:srcRect];
    [m_pImageViewFocus setAlpha:1.0];
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.50];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(focusAnimationStop)];
    [m_pImageViewFocus setFrame:rect];
    [m_pImageViewFocus setAlpha:0.0];
    [UIView commitAnimations];
}

// 双指捏-->Camera变焦
- (void)twoFingerPintch:(UIPinchGestureRecognizer *)gestureRecognizer
{
    if([gestureRecognizer state] == UIGestureRecognizerStateBegan)
    {
        _previewScale = [gestureRecognizer scale];
        [self showZoomBar];
    }
    
    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
        [gestureRecognizer state] == UIGestureRecognizerStateChanged)
    {
        CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
        
        CGFloat newScale = 1.0 - (_previewScale - [gestureRecognizer scale]);
        newScale = MIN(newScale, MAX_ZOOM_SCALE / currentScale);
        newScale = MAX(newScale, MIN_ZOOM_SCALE / currentScale);
        
        CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
        [gestureRecognizer view].transform = transform;
        
        _previewScale = [gestureRecognizer scale];
    }
    
    //set to zoom bar display
    CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:@"transform.scale"] floatValue];
    CGFloat barMax = m_pZoomSlider.m_pSlider.maximumValue;
    CGFloat barMin = m_pZoomSlider.m_pSlider.minimumValue;
    CGFloat barCur = (currentScale-MIN_ZOOM_SCALE)/(MAX_ZOOM_SCALE-MIN_ZOOM_SCALE)*(barMax-barMin) + barMin;
    [m_pZoomSlider setThumbValue:barCur];
    
    [self startZoomBarDisplayTimer];    
}

/* **************************************************************************
 * 按钮事件
 * *************************************************************************/
// 切换前后camera按钮事件
-(IBAction)OnBtnSwitchCamera:(id)sender
{
    if ([[CamCaptureManager singleton] cameraCount] > 1)
    {
        [[CamCaptureManager singleton] toggleCamera];
    }
}

// 在preview上是否检测人脸按钮事件
-(IBAction)OnBtnDetectFace:(id)sender
{
    BOOL bCurDetect = [CamCaptureManager singleton].m_bEnableVideoOutput;
    if (bCurDetect==YES) {
        [CamCaptureManager singleton].m_bEnableVideoOutput = NO;
        [self updateViewWithFaceCount:0 faceRects:nil];
    }
    else
    {
        [CamCaptureManager singleton].m_bEnableVideoOutput = YES;
    }
    
}

// 拍照按钮事件
-(IBAction)OnBtnTakePhoto:(id)sender
{
    if ([CamCaptureManager singleton]->m_takePhotoState == TAKEPHOTO_STATE_IDLE) {
        if ( ![CamCaptureManager singleton].m_pStillImageOutput.isCapturingStillImage) {
            [[CamCaptureManager singleton] captureStillImage];
        }
        [CamCaptureManager singleton]->m_takePhotoState = TAKEPHOTO_STATE_CAPTURING;
        [self.m_pBtnTakePhoto setEnabled:NO];
        [self showSpinner];
    }
}

// 闪光灯事件
// auto->off->on
-(IBAction)OnBtnFlash:(id)sender
{
    if(YES == [[CamCaptureManager singleton] hasFlash])
    {
        NSString *str = nil;
        NSInteger flash = [CamCaptureManager singleton]->m_pFlashMode;
        if(AVCaptureFlashModeAuto == flash){
            [[CamCaptureManager singleton] flashMode:AVCaptureFlashModeOff];
            str = @"自动";
        }
        else if(AVCaptureFlashModeOff == flash){
            [[CamCaptureManager singleton] flashMode:AVCaptureFlashModeOn];
            str = @"关闭";
        }
        else if(AVCaptureFlashModeOn == flash){
            [[CamCaptureManager singleton] flashMode:AVCaptureFlashModeAuto];
            str = @"打开";
        }
        [self.m_pBtnFlash setTitle:str forState:UIControlStateNormal];
    }
}

/* **************************************************************************
 * 回调函数
 * *************************************************************************/
// 获取每帧的preview数据时调用
-(void) captureManagerPreview:(CamCaptureManager*)captureManager didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
{
    static int i = 0;
    if ( ++i % 15 != 0 )
        return;
    UIImage *img = [ImageHelper imageFromSampleBuffer:sampleBuffer];
    WXFaceResult result[10] = {0};
    int width = img.size.width;
    int height= img.size.height;
    NSLog(@"width = %d, height = %d", width, height);
    int nFace = [m_pFaceDetectManager detectFaceFromImage:img result:result];
    if (nFace)
    {
        CGRect rect = {0};
        rect.origin.x = self.m_pViewPreview.bounds.size.width/2 - result[0].FaceReg.x;
        rect.origin.y = result[0].FaceReg.y;
        rect.size.width = result[0].FaceReg.width;
        rect.size.height= result[0].FaceReg.height;
        NSLog(@"x=%f, y=%f, width=%f, height=%f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
//        self.m_pViewPreview.m_faceRect = rect;
        [self updateViewWithFaceCount:1 faceRects:&rect];
    }
    else
    {
        [self updateViewWithFaceCount:0 faceRects:nil];
    }
}

// 从camera获取CMSampleBufferRef数据后调用
-(void) captureManagerStillImageCaptured:(CamCaptureManager*)captureManager didOutputSampleBuffer:(CMSampleBufferRef)buffer withError:(NSError*)error
{
    [self hideSpinner];
    self.m_pBtnTakePhoto.enabled = YES;
}

@end
 





















